package com.hxd.otc.utils;

import android.content.Context;

import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.OSS;
import com.alibaba.sdk.android.oss.OSSClient;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
import com.alibaba.sdk.android.oss.common.OSSLog;
import com.alibaba.sdk.android.oss.common.auth.OSSCredentialProvider;
import com.alibaba.sdk.android.oss.common.auth.OSSPlainTextAKSKCredentialProvider;
import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
import com.alibaba.sdk.android.oss.model.GetObjectRequest;
import com.alibaba.sdk.android.oss.model.GetObjectResult;
import com.alibaba.sdk.android.oss.model.ObjectMetadata;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 创建者     李海镔
 * 创建时间   2017/7/7 14:59
 * 描述	      ${TODO}
 * <p>
 * 更新者     $Author$
 * 更新时间   $Date$
 * 更新描述   ${TODO}
 */

public class AliyunUtils {
    public static String bucketName = "";

    public static String endpoint = "";

    public static String accessKeyId = "";
    public static String accessKeySecret = "";
    public static String securityToken;
    /**
     * 上传次数
     */
    int number;
    /**
     * 成功上传(本地文件名作为key,阿里云地址为value)
     */
    Map<String, Object> success = new HashMap<>();
    /**
     * 失败上传(返回失败文件的本地地址)
     */
    List<String> failure = new ArrayList<>();
    /**
     * 上传回调
     */
    UploadListener uploadListener;
    /**
     * 上传任务列表
     */
    List<OSSAsyncTask> ossAsyncTasks = new ArrayList<>();

    private static OSS instance;

    private static AliyunUtils aliyunUtils;

//    public static OSS getInstance() {
//        return instance;
//    }

    public static AliyunUtils getInstance() {
        if (aliyunUtils == null) {
            aliyunUtils = new AliyunUtils();
        }
        return aliyunUtils;
    }

    /**
     * 构造函数
     */
    public AliyunUtils() {
//        ClientConfiguration conf = new ClientConfiguration();
//        conf.setConnectionTimeout(20 * 1000); // 连接超时，默认15秒
//        conf.setSocketTimeout(20 * 1000); // socket超时，默认15秒
//        conf.setMaxConcurrentRequest(9); // 最大并发请求书，默认5个
//        conf.setMaxErrorRetry(3); // 失败后最大重试次数，默认2次
//        init(BaseApplication.getInstance());
    }

    public static void init(Context context) {
        //明文设置模式，建议测试使用
//        String endpoint = "http://oss-cn-hangzhou.aliyuncs.com";
        // 明文设置AccessKeyId/AccessKeySecret的方式建议只在测试时使用
//        OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(accessKeyId, accessKeySecret, securityToken);
        OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(accessKeyId, accessKeySecret);

        OSSLog.enableLog();

        instance = new OSSClient(context.getApplicationContext(), endpoint, credentialProvider);
    }

    /**
     * 无用
     *
     * @param context
     * @param accessKeyId
     * @param accessKeySecret
     * @param endpoint
     */
    public static void init(Context context, String accessKeyId, String accessKeySecret, String endpoint) {
        OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(accessKeyId, accessKeySecret);
        instance = new OSSClient(context, endpoint, credentialProvider);
    }

    /**
     * 上传文件
     *
     * @param objectKey
     * @param uploadFilePath
     * @param putObjectRequestOSSProgressCallback
     * @param putObjectRequestPutObjectResultOSSCompletedCallback
     */
    public void upLoadFileToAli(String objectKey, String uploadFilePath, OSSProgressCallback<PutObjectRequest> putObjectRequestOSSProgressCallback, OSSCompletedCallback<PutObjectRequest, PutObjectResult> putObjectRequestPutObjectResultOSSCompletedCallback) {
        // 构造上传请求
        PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, uploadFilePath);
        ObjectMetadata metadata = new ObjectMetadata();
        put.setMetadata(metadata);
        // 异步上传时可以设置进度回调
        put.setProgressCallback(putObjectRequestOSSProgressCallback);
        if (instance != null) {
            OSSAsyncTask task = instance.asyncPutObject(put, putObjectRequestPutObjectResultOSSCompletedCallback);
            ossAsyncTasks.add(task);
        }
    }

    /**
     * 下载指定文件
     *
     * @param objectKey
     * @param getObjectRequestGetObjectResultOSSCompletedCallback
     */
    public void getFileFromAli(String objectKey, OSSCompletedCallback<GetObjectRequest, GetObjectResult> getObjectRequestGetObjectResultOSSCompletedCallback) {
        GetObjectRequest get = new GetObjectRequest(bucketName, "<objectKey>");
        OSSAsyncTask task = instance.asyncGetObject(get, getObjectRequestGetObjectResultOSSCompletedCallback);
    }

    /**
     * 添加上传任务
     *
     * @param paths
     * @param listener
     */
    public void setDatas(final List<File> paths, UploadListener listener) {

        this.uploadListener = listener;
        ossAsyncTasks.clear();

        number = 0;
        success.clear();
        failure.clear();

        for (File path : paths) {
            /**
             * 阿里云上文件名称
             */
            String objectKey = UUID.randomUUID().toString();
            /**
             * 用户自定义参数
             */
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.addUserMetadata("filePath", path.getPath());
            objectMetadata.addUserMetadata("fileName", path.getName());
            objectMetadata.addUserMetadata("objectKey", objectKey);

            PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, path.getPath());
            put.setMetadata(objectMetadata);

            put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
                @Override
                public void onProgress(PutObjectRequest putObjectRequest, long currentSize, long totalSize) {

                }
            });
            /**
             * 上传任务
             */
            OSSAsyncTask task;
            task = instance.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                @Override
                public void onSuccess(PutObjectRequest request, PutObjectResult result) {
                    number++;
//                    LogUtils.e("number: " + number + " objectKey===" + request.getObjectKey());
//                    LogUtils.e("aliPath====" + formAliPath(request));
//                    LogUtils.e("fileName====" + request.getMetadata().getUserMetadata().get("fileName"));
                    success.put(request.getMetadata().getUserMetadata().get("fileName"), formAliPath(request));
                    if (number == paths.size()) {
                        if (uploadListener != null)
                            uploadListener.onUploadComplete(success, failure);
                    }
                }

                @Override
                public void onFailure(PutObjectRequest putObjectRequest, ClientException clientException, ServiceException serviceException) {
                    number++;
                    if (clientException != null) {
                        LogUtils.e("本地异常如网络异常等");
                        LogUtils.e("clientExcepion: " + clientException.getMessage());
                    }
                    if (serviceException != null) {
                        // 服务异常
                        LogUtils.e("ErrorCode===" + serviceException.getErrorCode());
                        LogUtils.e("RequestId===" + serviceException.getRequestId());
                        LogUtils.e("getHostId===" + serviceException.getHostId());
                        LogUtils.e("RawMessage===" + serviceException.getRawMessage());
                    }

                    failure.add(putObjectRequest.getMetadata().getUserMetadata().get("filePath"));
                    if (number == paths.size()) {
                        if (uploadListener != null)
                            uploadListener.onUploadComplete(success, failure);
                    }
                }
            });
            /**
             * 添加到上传记录
             */
            ossAsyncTasks.add(task);
        }
    }

    public OSSAsyncTask<PutObjectResult> uploadFile(File file, OSSProgressCallback<PutObjectRequest> putObjectRequestOSSProgressCallback, OSSCompletedCallback<PutObjectRequest, PutObjectResult> ossCompletedCallback) {
        /**
         * 阿里云上文件名称
         */
        String objectKey = UUID.randomUUID().toString() + "_" + file.getName();
        /**
         * 用户自定义参数
         */
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.addUserMetadata("filePath", file.getPath());
        objectMetadata.addUserMetadata("fileName", file.getName());
        objectMetadata.addUserMetadata("objectKey", objectKey);

        PutObjectRequest put = new PutObjectRequest(bucketName, objectKey, file.getPath());
        put.setMetadata(objectMetadata);

        put.setProgressCallback(putObjectRequestOSSProgressCallback);
        /**
         * 上传任务
         */
        return instance.asyncPutObject(put, ossCompletedCallback);
    }

    public void cancleTasks() {
        for (OSSAsyncTask task : ossAsyncTasks) {
            if (task.isCompleted()) {
            } else {
                task.cancel();
            }
        }
    }

    /**
     * 拼接远程访问地址
     *
     * @param putObjectRequest
     * @return
     */
    public static String formAliPath(PutObjectRequest putObjectRequest) {
        return "http://" + putObjectRequest.getBucketName() + "." + AliyunUtils.endpoint + "/" + putObjectRequest.getObjectKey();
    }

    public interface UploadListener {
        /**
         * 上传完成
         *
         * @param success
         * @param failure
         */
        void onUploadComplete(Map<String, Object> success, List<String> failure);

    }
}
